<template>
  <!-- Start: 3D Carousel HTML Structure (背景轮播图的HTML结构) -->
  <!-- Header is commented out as requested -->
  <!-- <header class="carousel-header">
    <h1>3D Carousel Background</h1>
    <h3>Based on a pen by <a href="https://www.twitter.com/johnblazek" target="_blank">@johnblazek</a></h3>
    <div id="fps">Framerate: 0/60 FPS</div>
  </header> -->

  <div id="contentContainer" class="trans3d">
    <section id="carouselContainer" class="trans3d">
      <!-- Carousel items (轮播项) -->
      <figure id="item1" class="carouselItem trans3d"><div class="carouselItemInner trans3d">1</div></figure>
      <figure id="item2" class="carouselItem trans3d"><div class="carouselItemInner trans3d">2</div></figure>
      <figure id="item3" class="carouselItem trans3d"><div class="carouselItemInner trans3d">3</div></figure>
      <figure id="item4" class="carouselItem trans3d"><div class="carouselItemInner trans3d">4</div></figure>
      <figure id="item5" class="carouselItem trans3d"><div class="carouselItemInner trans3d">5</div></figure>
      <figure id="item6" class="carouselItem trans3d"><div class="carouselItemInner trans3d">6</div></figure>
      <figure id="item7" class="carouselItem trans3d"><div class="carouselItemInner trans3d">7</div></figure>
      <figure id="item8" class="carouselItem trans3d"><div class="carouselItemInner trans3d">8</div></figure>
      <figure id="item9" class="carouselItem trans3d"><div class="carouselItemInner trans3d">9</div></figure>
      <figure id="item10" class="carouselItem trans3d"><div class="carouselItemInner trans3d">10</div></figure>
      <figure id="item11" class="carouselItem trans3d"><div class="carouselItemInner trans3d">11</div></figure>
      <figure id="item12" class="carouselItem trans3d"><div class="carouselItemInner trans3d">12</div></figure>
    </section>
  </div>
  <!-- End: 3D Carousel HTML Structure -->

  <!-- Start: File Upload Component Structure (文件上传组件的HTML结构) -->
  <div class="upload-container">
    <h2>上传数据文件（.txt）</h2>

    <!-- 表格选择 -->
    <div class="form-group">
      <label for="table-select">选择目标表格：</label>
      <select id="table-select" v-model="selectedTable" :disabled="isLoading">
        <option disabled value="">-- 请选择要上传的表 --</option>
        <option v-for="option in tableOptions" :key="option.value" :value="option.value">
          {{ option.text }}
        </option>
      </select>
    </div>

    <!-- 文件输入 -->
    <div class="form-group">
      <label for="file-input">选择TXT文件（以分号分隔）：</label>
      <input type="file" id="file-input" ref="fileInputRef" accept=".txt" @change="handleFileChange"
        :disabled="isLoading" />
    </div>

    <!-- 上传按钮 -->
    <div class="form-group">
      <button @click="handleUpload" :disabled="!selectedFile || !selectedTable || isLoading">
        {{ isLoading ? '正在上传...' : '上传' }}
      </button>
    </div>

    <!-- 状态消息 -->
    <div v-if="message" class="message" :class="{ 'error': isError }">
      {{ message }}
    </div>
  </div>
  <!-- End: File Upload Component Structure -->

</template>

<script setup>
  import { ref, onMounted, onUnmounted } from 'vue';
  import axios from '@/apiaxios/axiosInstance';
  import $ from 'jquery';
  import { gsap } from 'gsap';

  // --- File Upload Component State (文件上传组件的状态) ---
  const selectedTable = ref('');
  const selectedFile = ref(null);
  const isLoading = ref(false);
  const message = ref('');
  const isError = ref(false);
  const fileInputRef = ref(null);
  const tableOptions = [
    { value: 'user_flavor', text: 'user_flavor 用户个人喜好' },
		{ value: 'tab_rank', text: 'tab_rank 标签热度' },
		{ value: 'video_rank', text: 'video_rank 视频热度' }
  ];
	const tableurl = {
    "user_flavor": "/backend/userFlavor/addBatch",
		"tab_rank": "/backend/tabRank/addBatch",
		"video_rank": "/backend/videoRank/addBatch"
  };

  // --- File Upload Component Methods (文件上传组件的方法) ---
  const handleFileChange = (event) => {
		const file = event.target.files[0];
		if (file && file.type === 'text/plain') {
			selectedFile.value = file;
			message.value = `已选择文件：${file.name}`;
			isError.value = false;
		} else {
			selectedFile.value = null;
			if (fileInputRef.value) {
				fileInputRef.value.value = '';
			}
			if (file) {
				message.value = '请选择一个有效的.txt文件。';
				isError.value = true;
			} else {
				message.value = '';
				isError.value = false;
			}
		}
  };

  const handleUpload = () => {
		if (!selectedFile.value || !selectedTable.value) {
			message.value = '请选择一个表格和一个文件。';
			isError.value = true;
			return;
		}
		isLoading.value = true;
		isError.value = false;
		message.value = '正在读取文件...';
		const reader = new FileReader();
		reader.onload = async (e) => {
			try {
				const fileContent = e.target.result;
				message.value = '正在解析数据...';
				const lines = fileContent.split(/\r?\n/)
					.map(line => line.trim())
					.filter(line => line.length > 0);
				if (lines.length === 0) throw new Error("文件为空或仅包含空白字符。");

				let parsedData = [];
				// --- Data Parsing Logic (数据解析逻辑) ---
				if (selectedTable.value === 'user_flavor') {
					parsedData = lines.map((line, index) => {
						const fields = line.split(';');
						if (fields.length !== 4) throw new Error(`解析第 ${index + 1} 行出错：user_flavor表该行应包含4个字段。`);
						return { id: parseInt(fields[0].trim(), 10) || null, uid: parseInt(fields[1].trim(), 10), tname: fields[2].trim(), tpercent: fields[3].trim() };
					});
				} else if (selectedTable.value === 'video_rank') {
                    parsedData = lines.map((line, index) => {
						const fields = line.split(';');
						if (fields.length !== 3) throw new Error(`解析第 ${index + 1} 行时出错：video_rank表该行应包含3个字段。`);
						return { id: parseInt(fields[0].trim(), 10) || null, vid: parseInt(fields[1].trim(), 10), views: parseInt(fields[2].trim(), 10) };
					});
				} else if (selectedTable.value === 'tab_rank') {
					parsedData = lines.map((line, index) => {
						const fields = line.split(';');
						if (fields.length < 2 || fields.length > 4) throw new Error(`解析第 ${index + 1} 行时出错：tab_rank表该行应包含2到4个字段。`);
						const result = { id: parseInt(fields[0].trim(), 10) || null, tname: fields[1].trim().replace(/^"|"$/g, ''), cnt: fields.length >= 3 ? parseInt(fields[2].trim(), 10) : 0 };
						if (fields.length === 4) {
							result.uid = parseInt(fields[1].trim(), 10); result.tname = fields[2].trim().replace(/^"|"$/g, ''); result.cnt = parseInt(fields[3].trim(), 10);
						}
                        if (isNaN(result.id) || isNaN(result.cnt) || (result.uid !== undefined && isNaN(result.uid))) throw new Error(`解析第 ${index + 1} 行时出错：包含无效的数字字段。`);
						return result;
					});
				} else {
					throw new Error(`未知的表格类型: ${selectedTable.value}`);
				}
                // --- End Data Parsing ---

				message.value = `已解析 ${parsedData.length} 条记录。正在发送到服务器...`;
				await sendDataToBackend(selectedTable.value, parsedData);
				message.value = `已成功为表格 '${getTableName(selectedTable.value)}' 上传数据。`;
				isError.value = false;
				selectedFile.value = null;
				if (fileInputRef.value) fileInputRef.value.value = '';
			} catch (error) {
				console.error("上传处理出错：", error);
                let displayError = error.message;
                if (error.response?.data?.message) displayError = error.response.data.message;
                else if (error.message?.includes('Network Error')) displayError = "网络错误，无法连接到服务器。";
                else if (error.message?.includes('timeout')) displayError = "请求超时，请稍后再试。";
				message.value = `错误：${displayError}`;
				isError.value = true;
			} finally {
				isLoading.value = false;
			}
		};
		reader.onerror = (e) => {
			console.error("文件读取错误：", e);
			message.value = '读取文件时出错。'; isError.value = true; isLoading.value = false;
		};
		reader.readAsText(selectedFile.value, 'UTF-8');
  };

  const getTableName = (value) => {
      const option = tableOptions.find(opt => opt.value === value);
      return option ? option.text : value;
  };

  // --- Backend API Call (后端API调用) ---
  async function sendDataToBackend(tableName, data) {
      try {
        const response = await axios.post(tableurl[tableName], data, { headers: { 'Content-Type': 'application/json' } });
        if (response.status === 200) {
          if (response.data.code === 200) {
            console.log("后端响应成功:", response.data); return true;
          } else { throw new Error(response.data.message || `后端处理失败 (code: ${response.data.code})`); }
        } else { throw new Error(`服务器响应错误 (status: ${response.status})`); }
      } catch (error) {
        console.error("API调用错误:", error);
        if (error.response) {
             const backendErrorMessage = error.response.data?.message || error.response.data?.error || `请求失败 (status: ${error.response.status})`;
             throw new Error(backendErrorMessage);
        } else if (error.request) { throw new Error("无法连接到服务器，请检查网络。"); }
        else { throw error; }
      }
    }

  // --- 3D Carousel Logic (3D轮播图逻辑) ---
  let ticker = null; // 定时器句柄 (Timer handle)
  let w, container, carousel, item, radius, itemLength, rY; // 轮播图变量 (Carousel variables), removed 'fps'
  let mouseX = 0;
  let mouseY = 0;
  let mouseZ = 0;
  let addX = 0;

  // FPS counter is removed as the display element is gone
  // FPS 计数器已移除，因为显示它的元素已不存在

  // 初始化轮播图 (Initialize carousel)
  function initCarousel() {
    if (typeof $ === 'undefined' || typeof gsap === 'undefined') {
      console.error("jQuery or GSAP not loaded! Carousel cannot initialize."); return;
    }

    w = $(window);
    container = $('#contentContainer');
    carousel = $('#carouselContainer');
    item = $('.carouselItem');
    itemLength = item.length;
    // fps = $('#fps'); // Removed: The #fps element is gone (已移除：#fps 元素不存在了)

    if (!container.length || !carousel.length || !item.length || itemLength === 0) {
       console.error("Carousel HTML elements not found or itemLength is zero. Aborting init.");
       setTimeout(initCarousel, 100); return;
    }

    rY = 360 / itemLength;
    radius = Math.round((250) / Math.tan(Math.PI / itemLength));

    // 设置容器和轮播的3D属性 (Set 3D properties for container and carousel)
    gsap.set(container, { perspective: 600, width: '100%', height: '100%', position: 'fixed', top: 0, left: 0, zIndex: -1, overflow: 'hidden' });
    gsap.set(carousel, { z: -(radius), width: '100%', height: '100%', position: 'absolute', top: '50%', left: '50%', margin: '-500px 0 0 -500px'}); // Centering logic remains the same (居中逻辑保持不变)

    // 为每个轮播项创建属性和动画 (Create properties and animation for each item)
    for (let i = 0; i < itemLength; i++) {
      const $item = item.eq(i);
      const $block = $item.find('.carouselItemInner');
      if(!$item.length || !$block.length){ console.warn(`Carousel item ${i+1} or inner block not found.`); continue; }
      gsap.set($item, { rotationY: rY * i, z: radius, transformOrigin: "50% 50% " + -radius + "px", autoAlpha: 0 });
      animateIn($item, $block);
    }

    // 设置鼠标移动监听器和循环定时器 (Set up mouse move listener and loop timer)
    window.addEventListener("mousemove", onMouseMove, false);
    if (ticker) clearInterval(ticker);
    ticker = setInterval(looper, 1000 / 60);
  }

  // 入场动画函数 (Animate-in function)
  function animateIn($item, $block) {
    const $nrX = 360 * getRandomInt(2), $nrY = 360 * getRandomInt(2);
    const $nx = -2000 + getRandomInt(4000), $ny = -2000 + getRandomInt(4000), $nz = -4000 + getRandomInt(4000);
    const $s = 1.5 + (getRandomInt(10) * .1), $d = 1 - (getRandomInt(8) * .1);
    gsap.to($item, 0.5, { autoAlpha:1, delay:$d });
    gsap.set($block, { z: $nz, rotationY: $nrY, rotationX: $nrX, x: $nx, y: $ny, autoAlpha: 0 });
    gsap.to($block, $s, { delay: $d, rotationY: 0, rotationX: 0, z: 0, ease: 'expo.inOut' });
    gsap.to($block, $s - .5, { delay: $d, x: 0, y: 0, autoAlpha: 1, ease: 'expo.inOut' });
  }

  // 鼠标移动事件处理 (Mouse move event handler)
  function onMouseMove(event) {
     mouseX = -(-(window.innerWidth * .5) + event.pageX) * .0015;
	   mouseY = -(-(window.innerHeight * .5) + event.pageY ) * .005;
	   mouseZ = -(radius) - (Math.abs(-(window.innerHeight * .5) + event.pageY ) - 200) * 0.5;
  }

  // 循环更新轮播图位置 (Loop to update carousel position) - Removed FPS update
  // 循环更新轮播图位置 - 移除了FPS更新
  function looper() {
    addX += mouseX;
    if (carousel?.length) { // Optional chaining for safety
        gsap.to(carousel, 1, { rotationY: addX, rotationX: mouseY, ease: 'quint.out' });
        gsap.set(carousel, { z: mouseZ });
    }
     // FPS update logic is removed
     // FPS 更新逻辑已移除
  }

  // 获取随机整数工具函数 (Utility function to get random integer)
  function getRandomInt($n) {
    return Math.floor((Math.random() * $n));
  }

  // --- Lifecycle Hooks (生命周期钩子) ---
  onMounted(() => { setTimeout(initCarousel, 100); });
  onUnmounted(() => {
    if (ticker) clearInterval(ticker);
    window.removeEventListener("mousemove", onMouseMove, false);
    // Optional GSAP cleanup
     if (carousel?.length) gsap.killTweensOf(carousel);
     if (item?.length) {
         item.each(function() {
             gsap.killTweensOf($(this));
             gsap.killTweensOf($(this).find('.carouselItemInner'));
         });
     }
  });

</script>

<!-- NON-SCOPED styles for the 3D Carousel (轮播图的 非作用域 样式) -->
<style>
  /* hardware accelerator class (from original) */
  /* 硬件加速类 (来自原始代码) */
  .trans3d {
    -webkit-transform-style: preserve-3d; -webkit-transform: translate3d(0, 0, 0);
    -moz-transform-style: preserve-3d; -moz-transform: translate3d(0, 0, 0);
    -ms-transform-style: preserve-3d; -ms-transform: translate3d(0, 0, 0);
    transform-style: preserve-3d; transform: translate3d(0, 0, 0);
    -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
		-ms-backface-visibility:hidden; backface-visibility:hidden;
  }

  /* Carousel positioning and styling (adapted from original) */
  /* 轮播图定位和样式 (改编自原始代码) */
  /* Styles for .carousel-header are removed as the element is gone */
  /* .carousel-header 的样式已移除，因为元素已不存在 */

  #contentContainer {
    /* Positioned by GSAP in initCarousel */
    /* 由 GSAP 在 initCarousel 中定位 */
     background-color:#1a948d; /* Fallback background color */
     /* background-image: url('/path/to/your/background.jpg'); */
     background-size: cover; background-position: center center;
  }

  #carouselContainer { /* Positioned by GSAP in initCarousel / 由 GSAP 在 initCarousel 中定位 */ }

  .carouselItem {
    width: 320px; height: 130px; position: absolute;
    left: 50%; top: 50%; margin-left: -160px; margin-top: -90px;
    visibility: hidden; /* GSAP makes visible */
  }

  .carouselItemInner {
    width: 100%; height: 100%; /* Use 100% to fill parent */
    position: absolute; left: 0; top: 0;
    background-color: rgba(255, 255, 255, .75);
    border: 10px solid rgba(255, 255, 255, .5);
    color: #0056b3; font-size: 72px; text-align: center;
    padding-top: 50px; box-sizing: border-box; border-radius: 8px;
    overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.2);
  }
</style>

<!-- SCOPED styles for the File Upload component -->
<!-- 文件上传组件的 作用域内 样式 -->
<style scoped>
  * { margin: 0; padding: 0; box-sizing: border-box; }

  .upload-container {
    padding: 25px 30px; border: 1px solid #ccc; border-radius: 8px;
    max-width: 550px; margin: 15vh auto 0 auto; /* Adjusted top margin slightly */
    font-family: sans-serif; position: relative; z-index: 10;
    background-color: rgba(255, 255, 255, 0.92); /* Slightly less transparent */
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.12);
    color: #333;
  }

  .upload-container h2 {
      color: #333; text-align: center; margin-bottom: 20px; font-size: 1.5em;
  }

  .form-group { margin-bottom: 18px; }
  .form-group label {
    display: block; margin-bottom: 6px; font-weight: bold;
    color: #555; font-size: 14px;
  }
  .form-group select,
  .form-group input[type="file"],
  .form-group button {
    width: 100%; padding: 10px 12px; border: 1px solid #ccc;
    border-radius: 4px; font-size: 14px; color: #333;
  }
  .form-group select { background-color: #fff; }
  .form-group input[type="file"] { padding: 5px; background-color: #f8f8f8; }
  .form-group input[type="file"]::file-selector-button {
      padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px;
      background-color: #eee; cursor: pointer; margin-right: 10px;
      transition: background-color 0.2s ease; color: #333;
    }
  .form-group input[type="file"]::file-selector-button:hover { background-color: #ddd; }
  .form-group button {
    background-color: #007bff; color: white; border: none; cursor: pointer;
    transition: background-color 0.2s ease, opacity 0.2s ease;
    font-weight: bold; letter-spacing: 0.5px;
  }
  .form-group button:hover:not(:disabled) { background-color: #0056b3; }
  .form-group button:disabled { background-color: #cccccc; cursor: not-allowed; opacity: 0.7; }

  .message {
    margin-top: 20px; padding: 12px 15px; border-radius: 4px;
    background-color: #e9ecef; border: 1px solid #ced4da;
    color: #495057; text-align: center; font-size: 14px;
  }
  .message.error {
    color: #721c24; background-color: #f8d7da; border-color: #f5c6cb;
  }
</style>